<template>
  <div id="containerMap"></div>
</template>

<script lang="ts" setup>
import 'ol/ol.css'
import Map from 'ol/Map'
import View from 'ol/View'
import Feature from 'ol/Feature'
import TileLayer from 'ol/layer/Tile'
import VectorLayer from 'ol/layer/Vector'
import XYZ from 'ol/source/XYZ'
import GeoJSON from 'ol/format/GeoJSON.js'
import Point from 'ol/geom/Point.js'
import VectorSource from 'ol/source/Vector.js'
import { Fill, Stroke, Style, Icon } from 'ol/style.js'

import sz from './shenzhen.json'
import { mockData } from './index'

const map = shallowRef<any>(null)
const polygonLayer = ref<any>() // 红色区域
const szPolygonLayer = ref<any>() // 蓝色区域
const markeyLayer = ref<any>() // 深汕俩个图标所在图层
const dynamicMarkeyLayer = ref<any>() // 点击园区绘制点所在图层
const mapListdata = ref([])
const countryListdata = ref([])
const parkMarkerPoints = ref()

const scope = ref<Array<number[]>>([]) // 图层数组， 用于找到地图的层级和中心，调整最佳的可视区域范围

// 初始化地图
function initMap() {
  map.value = new Map({
    target: 'containerMap',
    layers: [
      new TileLayer({
        source: new XYZ({
          url: 'http://webst0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}'
        })
      })
    ],
    view: new View({
      projection: 'EPSG:4326', //使用这个坐标系
      center: [115.047662, 22.87461],
      zoom: 11
    })
  }) as any
  window.addEventListener('resize', resizeMap)
}

function resizeMap() {
  if (map.value) {
    map.value.updateSize()
  }
}

// 绘制区划范围，可自定义区域（ 以下为自定义区域例子， 规则的geojsonObject数据可使用高德api获取）
async function drawPolygon() {
  const polygons = mockData.map((k: any) => [k.lng, k.lat])

  const styles = [
    new Style({
      stroke: new Stroke({
        color: '#FF4000',
        width: 4
      }),
      fill: new Fill({
        color: 'rgba(255,64,0,0.3)'
      }),
      zIndex: 1
    })
  ]

  const geojsonObject = {
    type: 'FeatureCollection',
    crs: {
      type: 'name',
      properties: {
        name: 'EPSG:4326'
      }
    },
    features: [
      {
        type: 'Feature',
        geometry: {
          type: 'Polygon',
          coordinates: [polygons]
        }
      }
    ]
  }

  const source = new VectorSource({
    features: new GeoJSON().readFeatures(geojsonObject)
  })

  polygonLayer.value = new VectorLayer({
    source: source,
    style: styles,
    zIndex: 1
  })
  map.value.addLayer(polygonLayer.value)
  let extent2 = polygonLayer.value.getSource().getExtent()
  scope.value?.push(extent2)

  fitMapView()
}

// 调整地图层级和中心，使覆盖物全部展示在可视区域范围内
function fitMapView() {
  let minX: any = null
  let minY: any = null
  let maxX: any = null
  let maxY: any = null
  scope.value.forEach((item: any) => {
    if (minX === null) {
      minX = item[0]
      minY = item[1]
      maxX = item[2]
      maxY = item[3]
    } else {
      minX = Math.min(item[0], minX)
      minY = Math.min(item[1], minY)
      maxX = Math.max(item[2], maxX)
      maxY = Math.max(item[3], maxY)
    }
  })
  map.value
    .getView()
    .fit([minX, minY, maxX, maxY], { nearest: true, padding: [50, 320, 50, 50], duration: 1000 })
}

// 绘制深圳合作区范围
async function drawSZPolygon() {
  const styles = [
    new Style({
      stroke: new Stroke({
        color: '#0858FD',
        width: 2
      }),
      fill: new Fill({
        color: 'rgba(111, 158, 255, 0.35)'
      }),
      zIndex: 1
    })
  ]
  const source = new VectorSource({
    features: new GeoJSON().readFeatures(sz)
  })

  szPolygonLayer.value = new VectorLayer({
    source: source,
    style: styles,
    zIndex: 1
  }) as any
  ;(map.value as any).addLayer(szPolygonLayer.value)
  let extent1 = szPolygonLayer.value.getSource().getExtent()
  scope.value?.push(extent1)
}

// 去除范围
function removePolygon() {
  map.value && map.value.removeLayer(polygonLayer.value)
  map.value && map.value.removeLayer(szPolygonLayer.value)
}

function filterpark(val: any) {
  removeMarker()
  const parkPolyganPoints = parkMarkerPoints.value.filter((item: any) => {
    return item.name === val.parkName
  })
  if (parkPolyganPoints && parkPolyganPoints.length > 0) {
    const vectorSource = new VectorSource()
    dynamicMarkeyLayer.value = new VectorLayer({
      source: vectorSource,
      zIndex: 2
    })
    // 添加图层
    map.value.addLayer(dynamicMarkeyLayer.value)

    const iconFeature = new Feature({
      geometry: new Point([val.lng, val.lat])
    })

    // 设置样式，这里使用图片
    iconFeature.setStyle(
      new Style({
        image: new Icon({
          src: 'static/shenshan/tips1.png',
          scale: 0.6
        })
      })
    )

    // 将图片Feature添加到Source
    dynamicMarkeyLayer.value.getSource().addFeature(iconFeature)
    map.value.getView().animate({ center: [val.lng, val.lat], duration: 1000 })
  } else {
    window.$message('info', '尚未获取到园区坐标')
  }
}

function removeMarker() {
  map.value && map.value.removeLayer(dynamicMarkeyLayer.value)
}

// 添加落点示例
function drawLocationIcon() {
  const vectorSource = new VectorSource()
  markeyLayer.value = new VectorLayer({
    source: vectorSource,
    zIndex: 2
  })
  // 添加图层
  map.value.addLayer(markeyLayer.value)

  const images = [
    {
      scale: 0.6,
      anchor: undefined,
      imgUrl: 'images/tips1.png'
    },
    {
      scale: 0.4,
      anchor: [585, 150],
      imgUrl: 'images/tips3.png'
    }
  ]

  images.forEach((k: any, index: number) => {
    const iconFeature = new Feature({
      geometry: new Point([114.052672, 22.509184])
    })

    let iconOptions = {}
    if (index === 1) {
      iconOptions = {
        anchor: k.anchor, // 偏移的 x 与 y 方向值，注意此值与 Cesium 等GIS库偏向方向正好相反
        anchorXUnits: 'pixels',
        anchorYUnits: 'pixels'
      }
    }

    // 设置样式，这里使用图片
    iconFeature.setStyle(
      new Style({
        image: new Icon({
          ...iconOptions,
          src: k.imgUrl,
          scale: k.scale
        })
      })
    )
    markeyLayer.value.getSource().addFeature(iconFeature)
  })
}

function getMapParameters() {
  initMap()
  drawSZPolygon()
  drawPolygon()
  drawLocationIcon()
}

onMounted(() => {
  getMapParameters()
})

onUnmounted(() => {
  if (map.value) {
    polygonLayer.value = null
    szPolygonLayer.value = null

    markeyLayer.value = null
    dynamicMarkeyLayer.value = null
    map.value.setTarget(null)
    map.value.dispose()
    window.removeEventListener('resize', resizeMap)
  }
})
</script>

<style scoped lang="less">
#containerMap {
  width: 100%;
  height: 100%;
}
</style>
